﻿namespace HandlerContextOptions
{

    /**
        Downstream : 下游服务配置
        UpStream : 上游服务配置
        Aggregates : 服务聚合配置
        ServiceName, LoadBalancer, UseServiceDiscovery : 配置服务发现
        AuthenticationOptions : 配置服务认证
        RouteClaimsRequirement : 配置Claims鉴权
        RateLimitOptions : 为限流配置
        FileCacheOptions : 缓存配置
        QosOptions : 服务质量与熔断
        DownstreamHeaderTransform : 头信息转发
        DownstreamPathTemplate：下游戏
        DownstreamScheme：下游服务http schema
        DownstreamHostAndPorts：下游服务的地址，如果使用LoadBalancer的话这里可以填多项
        UpstreamPathTemplate: 上游也就是用户输入的请求Url模板
        UpstreamHttpMethod: 上游请求http方法，可使用数组
        Prioirty优先级： 对多个产生冲突的路由设置优化级
        路由负载均衡：
        当下游服务有多个结点的时候，我们可以在DownstreamHostAndPorts中进行配置。
     */


    public class GatewayGlobalOption
    {
        /// <summary>
        /// 外部暴露的Url
        /// </summary>
        public string BaseUrl { get; set; }

        /// <summary>
        /// 限流扩展配置
        /// </summary>
        public RateLimitOptions RateLimitOptions { get; set; }

        /// <summary>
        /// 服务质量与熔断
        /// </summary>
        public QoSOptions QoSOptions { get; set; }

        /// <summary>
        /// 负载均衡的算法
        /// </summary>
        public LoadBalancerOptions LoadBalancerOptions { get; set; }

        /// <summary>
        /// 下游服务http schema
        /// </summary>
        public string DownstreamScheme { get; set; } = "http";

        /// <summary>
        /// 跟踪重定向/使用Cookie容器
        /// </summary>
        //public HttpHandlerOptions HttpHandlerOptions { get; set; }
    }

    /// <summary>
    /// 限流扩展配置
    /// </summary>
    public class RateLimitOptions
    {
        /// <summary>
        /// Http头  X-Rate-Limit 和 Retry-After 是否禁用
        /// </summary>
        public bool DisableRateLimitHeaders { get; set; } = false;

        /// <summary>
        /// 当请求过载被截断时返回的消息
        /// </summary>
        public string QuotaExceededMessage { get; set; } = "你的访问过于频繁请稍后在试";

        /// <summary>
        /// 当请求过载被截断时返回的http status
        /// </summary>
        public int HttpStatusCode { get; set; } = 503;

        /// <summary>
        /// 用来识别客户端的请求头，默认是 ClientId
        /// </summary>
        public string ClientIdHeader { get; set; } = "ClientId";
    }


    /// <summary>
    /// 服务质量与熔断
    /// </summary>
    public class QoSOptions
    {
        /// <summary>
        /// 允许多少个异常请求
        /// 必须 > 0
        /// </summary>
        public int ExceptionsAllowedBeforeBreaking { get; set; } = 10;

        /// <summary>
        /// 熔断的时间，单位为毫秒
        /// 单位/ms
        /// </summary>
        public int DurationOfBreak { get; set; } = 5000;

        /// <summary>
        /// 如果请求超过{TimeoutValue}秒钟，它将自动超时
        /// 单位/ms
        /// </summary>
        public int TimeoutValue { get; set; } = 20000;
    }

    /// <summary>
    /// 负载均衡的算法
    /// </summary>
    public class LoadBalancerOptions
    {
        public LoadBalancerEnum Type { get; set; } = LoadBalancerEnum.RoundRobin;
    }

    /// <summary>
    /// 负载均衡类型
    /// </summary>
    public enum LoadBalancerEnum
    {
        /// <summary>
        /// 跟踪哪些服务正在处理请求，并将新请求发送到具有最少现有请求的服务
        /// </summary>
        LeastConnection,

        /// <summary>
        /// 遍历可用服务并发送请求
        /// </summary>
        RoundRobin,

        /// <summary>
        /// 从配置或服务发现中获取第一个可用服务
        /// </summary>
        NoLoadBalancer,

        /// <summary>
        /// 使用cookie将所有请求粘贴到特定服务器
        /// </summary>
        //CookieStickySessions
    }

    /// <summary>
    /// 跟踪重定向/使用Cookie容器
    /// </summary>
    public class HttpHandlerOptions
    {

        /// <summary>
        /// 是否隐式 Redirect
        /// </summary>
        public bool AllowAutoRedirect { get; set; }

        /// <summary>
        /// 是否开启路由追踪
        /// </summary>
        public bool UseTracing { get; set; }

        /// <summary>
        /// 是一个表明当发送请求时是否处理使用CookieContainer 属性存储服务器cookies 并且用这些cookies
        /// 默认值false。请注意，如果你为每一个下游服务使用CookieContainer，Ocelot会缓存HttpClient。
        /// 这就意味着所有下游服务请求都讲共享一个cookies。Issue 274 被创建是因为用户注意到cookies是可以被共享的。
        /// 我尝试考虑一种好的方式去处理这个，但是我认为这是不可能的。如果你不缓存client那就是说每个请求都获得一个新的client并因此都有一个新的cookies container。
        /// 如果你清楚了来自缓存客户端容器的缓存，那么你将获得竞争条件在请求中（并发）。这也就是说后面的请求不会使用来自前一个响应的cookies！总而言之，这是不好的。
        /// 我建议设置UseCookieContainer 为true 除非你有足够的好理由。只需查看你的响应头并在你的下个请求转发回cookies！
        /// </summary>
        public bool UseCookieContainer { get; set; }
    }


}
